package pr1.cromosoma;

public abstract class Cromosoma<E> implements Cloneable {

	private final boolean[] genes;
	private double aptitud;
	private double puntuacion;
	
	public Cromosoma(int longitudCromosoma) {

		genes = new boolean[longitudCromosoma];

        for (int i = 0; i < longitudCromosoma; i++) {
			genes[i] = Math.random() < 0.5;
		}
	}

	public double getAptitud() {
		return aptitud;
	}

	public void setAptitud(double aptitud) {
		this.aptitud = aptitud;
	}

	public double getPuntuacion() {
		return puntuacion;
	}

	public void setPuntuacion(double puntuacion) {
		this.puntuacion = puntuacion;
	}

	public boolean[] getGenes() {
		return genes;
	}

    public void copia(Cromosoma<E> otro) {
        assert(otro.genes.length == this.genes.length) : "La longitud de ambos cromosomas debe ser "
                + "la misma";
        System.arraycopy(otro.genes, 0, genes, 0, genes.length);
        aptitud = otro.aptitud;
        puntuacion = otro.puntuacion;
    }

	public double bin2dec(int desplazamiento, int longitud) {
		long num = 0;
		int peso = 1;
		for (int i = desplazamiento + longitud - 1; i >= desplazamiento; i--) {
			if (genes[i])
				num += peso;
            peso *= 2;
		}
		return num;
	}

    public boolean muta(double prob) {
        boolean mutado = false;
        for(int i = 0; i < genes.length; i++) {
            if(Math.random() < prob) {
                genes[i] = !genes[i];
                mutado = true;
            }
        }
        return mutado;
    }

	public abstract E getFenotipo();

	public abstract double evalua();
    public abstract Cromosoma<E> clone();
}
